/*!
 Temelia - Vector interface.

 Copyright (C) 2008, 2009 Ceata (http://ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef VECTOR_H_
#define VECTOR_H_

#include "platform.h"

struct _vector_t;
typedef struct _vector_t *vector_t;

/*!
 * @brief Returns an empty vector with maximum capacity keys.
 * Default capacity increment step is capacity.
 * O(1) complexity
 *
 * @param Vector's capacity
 */
DECLSPEC vector_t vector_new(int capacity);

/*!
 * @brief Frees the memory allocated by the library for this vector.
 * O(1) complexity
 *
 * @param Vector
 */
DECLSPEC void vector_delete(vector_t vector);

/*!
 * @brief Deep clones vector; it gives you a function to clone
 * keys in vector.
 * Complexity O(n)
 *
 * @param Vector
 * @param Cloning function
 * @param Context
 */
DECLSPEC vector_t vector_clone(vector_t vector, void *(*clone)(void *key,
		void *context), void *context);

/*!
 * @brief Clear method. Sets all internal pointers to NULL.
 * O(n) complexity
 *
 * @param Vector
 */
DECLSPEC void vector_clear(vector_t vector);

/*!
 * @brief Returns vector's capacity.
 * O(1) complexity
 *
 * @param Vector
 */
DECLSPEC int vector_get_capacity(vector_t vector);

/*!
 * @brief Returns vector's number of keys.
 * O(1) complexity
 *
 * @param Vector
 */
DECLSPEC int vector_get_size(vector_t vector);

/*!
 * @brief Returns vector's capacity increment step.
 * O(1) complexity
 *
 * @param Vector
 */
DECLSPEC int vector_get_capacity_increment(vector_t vector);

/*!
 * @brief Returns vector's data internal representation; cast it to void **.
 * O(1) complexity
 *
 * @param Vector
 */
DECLSPEC void *vector_get_internal_representation(vector_t vector);

/*!
 * @brief Sets vector's number of keys to a new value. If new number is bigger
 * then the old one, the last new vector keys will have NULL value; if not, then
 * you may loose some keys. The vector it's not adjusting it's capacity.
 * O(1) complexity
 *
 * @param Vector
 * @param New keys number.
 */
DECLSPEC void vector_set_size(vector_t vector, int new_size);

/*!
 * @brief Sets the capacity increment of the current vector.
 * O(1) complexity
 *
 * @param Vector
 * @param New capacity increment value
 */
DECLSPEC void vector_set_capacity_increment(vector_t vector,
		int new_capacity_increment);

/*!
 * @brief Sets an key, at specified position, to a value in vector.
 * O(1) complexity
 *
 * @param Vector
 * @param Position
 * @param Pointer to key
 */
DECLSPEC void vector_set_key_at(vector_t vector, int position, void *key);

/*!
 * @brief Returns component at a specified position in vector.
 * O(1) complexity
 *
 * @param Vector
 * @param Position
 */
DECLSPEC void *vector_get_key_at(vector_t vector, int position);

/*!
 * @brief Swaps the keys from given indexes.
 * O(1) complexity
 *
 * @param Vector
 * @param First index
 * @param Second index
 */
DECLSPEC void vector_swap(vector_t vector, int index1, int index2);

/*!
 * @brief Pushes key to the front of vector.
 * O(n) complexity
 *
 * @param Vector
 * @param key.
 */
DECLSPEC void vector_push_front(vector_t vector, void *key);

/*!
 * @brief Pushes key to the back of vector.
 * O(1) complexity
 *
 * @param Vector
 * @param key.
 */
DECLSPEC void vector_push_back(vector_t vector, void *key);

/*!
 * @brief Inserts before_key before key. If F is not found then E is pushed front.
 * O(n) complexity
 *
 * @param Address of pointer to vector.
 * @param Key about to add in
 * @param Pointer to searched key
 * @param Pointer to comparison function
 */
DECLSPEC void vector_push_before(vector_t vector, void *new_key, void *key,
		int compare(void *x, void *y, void *context), void *context);

/*!
 * @brief Inserts in vector an key after_key after another key key.
 * If key is not found then after_key is pushed back.
 * O(n) complexity
 *
 * @param Vector
 * @param Key about to add in
 * @param Pointer to searched key
 * @param Pointer to comparison function
 */
DECLSPEC void vector_push_after(vector_t vector, void *new_key, void *key,
		int compare(void *x, void *y, void *context), void *context);

/*!
 * @brief Removes the key from the vector.
 * O(n) complexity
 *
 * @param Vector
 * @param Key
 * @param Pointer to comparison function
 */
DECLSPEC void *vector_remove_key(vector_t vector, void *key, int compare(
		void *x, void *y, void *context), void *context);

/*!
 * @brief Removes key given by its index.
 * O(n) complexity
 *
 * @param Vector
 * @param Index
 */
DECLSPEC void *vector_remove_key_at(vector_t vector, int index);

/*!
 * @brief Returns and removes last key.
 * O(1) complexity
 *
 * @param Vector
 */
DECLSPEC void *vector_pop_back(vector_t vector);

/*!
 * @brief Returns and removes first key.
 * O(n) complexity
 *
 * @param Vector
 */
DECLSPEC void *vector_pop_front(vector_t vector);

/*!
 * @brief Finds an key in vector V and returns the position of the key, or -1
 * if the search failed.
 * O(n) complexity
 *
 * @param Vector
 * @param Key
 * @param Pointer to comparison function
 */
DECLSPEC int vector_search(vector_t vector, void *key, int compare(void *x,
		void *y, void *context), void *context);

/*!
 * @brief Tests if vector is empty.
 * O(1) complexity
 *
 * @param Vector
 */
DECLSPEC int vector_is_empty(vector_t vector);

/*!
 * @brief Tests if vector is full.
 * O(1) complexity
 *
 * @param Vector
 */
DECLSPEC int vector_is_full(vector_t vector);

/*!
 * @brief Sorts the vector's keys using randomized quicksort.
 * O(n*log(n)) complexity
 *
 * @param Vector
 * @param Pointer to comparison function
 */
DECLSPEC void vector_sort(vector_t vector, int compare(void *x, void *y,
		void *context), void *context);

/*!
 * @brief Iterates over the keys of current vector.
 * O(n) complexity
 *
 * @param Vector
 * @param Pointer to iterating function
 * @param Pointer to context - you may store here a structure with a FILE pointer if
 * you want to print the vector's keys
 */
DECLSPEC void vector_iterate(vector_t vector, void(*key_handler)(void *key,
		void *context), void *context);

/*!
 * @brief Returns a reference to the minimum key in vector.
 * O(n) complexity
 *
 * @param Vector
 * @param Pointer to comparison function
 */
DECLSPEC void *vector_min(vector_t vector, int compare(void *x, void *y,
		void *context), void *context);

/*!
 * @brief Returns a reference to the maximum key in vector.
 * O(n) complexity
 *
 * @param Vector
 * @param Pointer to comparison function
 */
DECLSPEC void *vector_max(vector_t vector, int compare(void *x, void *y,
		void *context), void *context);

#endif /* VECTOR_H */
